package com.xhwl.data.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.query.cent.sdata.PermissionQuery;
import com.xhwl.data.dao.IAccountOrganizationDao;
import com.xhwl.data.dao.IAppDao;
import com.xhwl.data.dao.IRolePermissionDao;
import com.xhwl.data.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @description:
 * @author:
 * @create: 2020-11-25
 **/
@Service
public class RolePermissionServiceImpl extends ServiceImpl<IRolePermissionDao, RolePermission> implements IRolePermissionService {
    private static final Logger log = LoggerFactory.getLogger(RolePermissionServiceImpl.class);
    @Autowired
    IRolePermissionDao rolePermissionDao;
    @Autowired
    IRoleService roleService;
    @Autowired
    IPermissionService permissionService;
    @Autowired
    IAccountRoleService accountRoleService;
    @Autowired
    IAppDao appDao;
    @Autowired
    IAccountOrganizationDao accountOrganizationDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRolePermission(Integer roleId, List<Integer> permissionIdList) {
        //先删除后新增
        UpdateWrapper<RolePermission> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("role_id", roleId);
        rolePermissionDao.delete(updateWrapper);
        List<RolePermission> rolePermissionList = new ArrayList<>(permissionIdList.size());
        for (int pId : permissionIdList) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setPermissionId(pId);
            rolePermission.setRoleId(roleId);
            rolePermissionList.add(rolePermission);
        }
        //批量新增 角色关联权限
        saveBatch(rolePermissionList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRolePermission(List<Integer> roleIdList, List<Integer> permissionIdList) {
        try {
            UpdateWrapper<RolePermission> updateWrapper = new UpdateWrapper();
            if (!CollectionUtils.isEmpty(roleIdList)) {
                updateWrapper.in("role_id", roleIdList);
            }
            if (!CollectionUtils.isEmpty(permissionIdList)) {
                updateWrapper.in("permission_id", permissionIdList);
            }
            rolePermissionDao.delete(updateWrapper);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new BusinessException("删除角色权限关联表失败");
        }

    }

    /**
     * 根据角色id获取权限list
     *
     * @param roleIdList
     * @return
     */
    @Override
    public List<Integer> getPermissionIdByRoleId(List<Integer> roleIdList) {
        QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
        rolePermissionQueryWrapper.select("permission_id");
        rolePermissionQueryWrapper.in("role_id", roleIdList);
        List<RolePermission> rolePermissionList = rolePermissionDao.selectList(rolePermissionQueryWrapper);
        List<Integer> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(permissionIdList)) {
            permissionIdList = permissionIdList.stream().distinct().collect(Collectors.toList());
        }
        return permissionIdList;

    }

    @Override
    public List<Permission> getPermissionByRoleId(List<Integer> roleIdList) {
        if (CollectionUtils.isEmpty(roleIdList)) {
            return Collections.emptyList();
        }
        List<Integer> permissionIds = getPermissionIdByRoleId(roleIdList);
        if (permissionIds.isEmpty()) {
            log.info("角色暂未关联权限信息");
            return Collections.emptyList();
        }
        PermissionQuery permissionQuery = new PermissionQuery();
        permissionQuery.setIdList(permissionIds);
        return permissionService.getPermissionList(permissionQuery);
    }

    @Override
    public List<Integer> getRoleByPermission(List<Integer> permissionIdList) {
        QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
        rolePermissionQueryWrapper.in("permission_id", permissionIdList);
        List<RolePermission> rolePermissions = this.list(rolePermissionQueryWrapper);
        List<Integer> roleIdList = rolePermissions.stream().map(RolePermission::getRoleId).collect(Collectors.toList());
        return roleIdList;
    }

    /**
     * 获取超级管理员的权限 list
     *
     * @return
     */
    @Override
    public List<Permission> getSuperManagerPermission(Account account) {
        List<Permission> permissionList = new ArrayList<>();
        PermissionQuery permissionQuery = new PermissionQuery();
        permissionQuery.setIndustryId(account.getIndustryId());

        permissionList = permissionService.getPermissionList(permissionQuery);
        if (CollectionUtils.isEmpty(permissionList)) {
            return permissionList;
        }
        return permissionList;
    }


    /**
     * 获取企业管理员的权限 list
     *
     * @param account
     * @return
     */
    @Override
    public List<Permission> getEnterpriseManagePermission(Account account) {
        List<Permission> permissionList = new ArrayList<>();
        //校验该账号是否关联企业
        QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
        accountOrganizationQueryWrapper.eq("account_id", account.getId());
        List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrganizationQueryWrapper);
        List<Integer> enterpriseIdList = accountOrganizations.stream().map(e -> e.getEnterpriseId()).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(enterpriseIdList)) {
            log.warn("该帐号 {} {} 没有关联企业", account.getId(), account.getLoginName());
            return permissionList;
        }
        //账号角色信息
        List<Integer> roleIdList = accountRoleService.findRoleIdByAccountId(account.getId());
        if (CollectionUtils.isEmpty(roleIdList)) {
            log.warn("该帐号 {} {} 没有关联角色", account.getId(), account.getLoginName());
            return permissionList;
        }
        List<Integer> permissionIdList = getPermissionIdByRoleId(roleIdList);
        if (CollectionUtils.isEmpty(permissionIdList)) {
            return permissionList;
        }
        PermissionQuery permissionQuery = new PermissionQuery();
        permissionQuery.setIdList(permissionIdList);
        permissionQuery.setOrderColumn("sort_num");
        permissionQuery.setOrderAsc(false);
        //账号权限信息
        permissionList = permissionService.getPermissionList(permissionQuery);
        return permissionList;
    }

    /**
     * 普通账号获取权限 list 根据企业，项目权限取交集
     *
     * @param account
     * @return
     */
    @Override
    public List<Permission> getCommonAccountPermission(Integer projectId, Account account,App app) {

        //企业权限
        List<Permission> enPermissionByAccount = permissionService.getEnPermissionByAccount(account);
        //企业权限Map (企业级别的权限是范围最广的)
        Map<Integer, Permission> permissionMap = enPermissionByAccount.stream().collect(Collectors.toMap(Permission::getId, Function.identity()));

        //项目权限
        List<Permission> proPermissionByAccount = permissionService.getProPermissionByAccount(account);
        //项目权限Map
        Map<Integer, Permission> permissionProjectMap = proPermissionByAccount.stream().collect(Collectors.toMap(Permission::getId, Function.identity()));

        //角色权限
        List<Permission> rolePermissionByAccount = permissionService.getRolePermissionByAccount(projectId, account,app);
        //角色权限Map
        Map<Integer, Permission> permissionRoleMap = rolePermissionByAccount.stream().collect(Collectors.toMap(Permission::getId, Function.identity()));

        //过滤出 最终的权限交集
        permissionMap = permissionMap.entrySet().stream().filter(e -> permissionProjectMap.containsKey(e.getKey()))
                .filter(e -> permissionRoleMap.containsKey(e.getKey()))
                .collect(LinkedHashMap::new, (m, e) -> m.put(e.getKey(), e.getValue()), LinkedHashMap::putAll);

        if (CollectionUtils.isEmpty(permissionMap)) {
            return Collections.emptyList();
        }
        return new ArrayList<>(permissionMap.values());
    }


}
